package JDBC.Pool;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;

public abstract class Pool {
//    private Logger logger = LoggerFactory.getLogger(Pool.class);

    public String propertiesName = "db.properties";
    private static Pool instance = null;

    //最大连接数
    protected int maxConnection = 100;

    //保持连接数
    protected int stayConnection = 10;

    //驱动字符串
    protected String driverName = null;

    //驱动类
    protected Driver driver = null;

    protected Pool(){
        try{
            init();
            loadDrivers(driverName);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * @Author cgw
     * @Description 初始化所有从配置文件中读取的成员变量
     * @return: void
     * @Date  2022/2/18 16:13
     **/
    private void init() throws IOException{
        Properties properties = new Properties();
        InputStream is = Pool.class.getClassLoader().getResourceAsStream(propertiesName);
        try {
            properties.load(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
        this.driverName = properties.getProperty("driverClassName");

        if(properties.getProperty("maxConnection")!=null){
            this.maxConnection = Integer.parseInt(properties.getProperty("maxConnection"));
        }

        if(properties.getProperty("stayConnection")!=null){
            this.stayConnection = Integer.parseInt(properties.getProperty("stayConnection"));
        }
    }

    /**
     * @Author cgw
     * @Description 装载和注册所有JDBC驱动程序
     * @param driverName: 接收驱动字符串
     * @return: void
     * @Date  2022/2/18 16:12
     **/
    private void loadDrivers(String driverName){
        String driverClassName= driverName;
        try {
            driver = (Driver) Class.forName(driverClassName).newInstance();
            DriverManager.registerDriver(driver);
//            logger.info("成功注册JDBC驱动程序:{}",driverClassName);
        } catch (Exception e) {
//            logger.info("无法注册JDBC驱动程序:{}，异常:{}",driverClassName,e);
        }
    }
    
    /**
     * @Author cgw
     * @Description 获得一个可用的连接，如果没有，则创建一个连接，并且小于最大连接限制
     * @return: java.sql.Connection
     * @Date  2022/2/18 16:01
     **/
    public abstract Connection getConnection();

    /**
     * @Author cgw
     * @Description 获得一个连接，有时间限制
     * @param time: 设置该连接的持续时间(以毫秒为单位)
     * @return: java.sql.Connection
     * @Date  2022/2/18 16:02
     **/
    public abstract Connection getConnection(long time);

    /**
     * @Author cgw
     * @Description 将连接对象返回连接池
     * @param connection: 获得连接对象
     * @return: void
     * @Date  2022/2/18 16:03
     **/
    public abstract void freeConnection(Connection connection);

    /**
     * @Author cgw
     * @Description 返回当前空闲的连接数
     * @return: int
     * @Date  2022/2/18 16:04
     **/
    public abstract int getNumFree();

    /**
     * @Author cgw
     * @Description 返回当前工作的连接数
     * @return: int
     * @Date  2022/2/18 16:04
     **/
    public abstract int getNumActive();

    /**
     * @Author cgw
     * @Description 关闭所有连接，撤销驱动注册，此方法为单例方法
     * @return: void
     * @Date  2022/2/18 16:14
     **/
    protected synchronized void release(){
        try{
            DriverManager.deregisterDriver(driver);
//            logger.info("撤销JDBC驱动程序:{}",driver.getClass().getName());
        } catch (SQLException e) {
//            logger.info("无法撤销JDBC驱动程序:{},异常:{}",driver.getClass().getName(),e);
        }

    }
}
